//package com.ruge.spring.cloud.gateway.base.exception;
//
//import com.ruge.spring.cloud.gateway.base.response.Response;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.HttpStatus;
//import org.springframework.http.MediaType;
//import org.springframework.http.ResponseEntity;
//import org.springframework.validation.ObjectError;
//import org.springframework.web.bind.MethodArgumentNotValidException;
//import org.springframework.web.bind.annotation.ControllerAdvice;
//import org.springframework.web.bind.annotation.ExceptionHandler;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.context.request.WebRequest;
//import org.springframework.web.method.HandlerMethod;
//import org.springframework.web.reactive.HandlerMapping;
//import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
//import org.springframework.web.util.WebUtils;
//
//import java.util.ArrayList;
//import java.util.HashSet;
//import java.util.List;
//import java.util.Set;
//import java.util.stream.Collectors;
//
///**
// * @author 嘿丷如歌
// * @version V1.0
// * @Description: 全局异常类
// * @date 2021/4/26 19:58
// */
//@ControllerAdvice
//public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
//    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
//
//    /**
//     * 父类中的handle方法只会处理spring mvc的异常，如果是其他异常，则会交由该方法处理
//     *
//     * @param ex
//     * @return
//     */
//    @ExceptionHandler(Throwable.class)
//    public final ResponseEntity<Object> handleExceptionGlobal(Throwable ex, WebRequest request, HandlerMethod handlerMethod) {
//        addMethodProduces(request, handlerMethod);
//        if (!(ex instanceof BaseBusinessException)) {
//            try {
//                return super.handleException((Exception) ex, request);
//            } catch (Exception e) {
//                // 由于spring 5.x对handleException的修改，对不认识的错误，直接抛出，此处按照4.x的方式进行处理
//                if (LOGGER.isWarnEnabled()) {
//                    LOGGER.warn("Unknown exception type: " + e.getClass().getName());
//                }
//                HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
//                return handleExceptionInternal(e, null, new HttpHeaders(), status, request);
//            }
//        }
//        BaseBusinessException exception = (BaseBusinessException) ex;
//        IError error = exception.getError();
//        Response errorBody = new Response();
//        errorBody.setStatus(Response.Status.FAILED);
//        errorBody.setErrorCode(error.getErrorCode());
//        errorBody.setErrorMessage(error.getErrorMessage());
//        errorBody.setExtMessage(exception.getExtMessage());
//
//        return new ResponseEntity<>(errorBody, null, HttpStatus.OK);
//    }
//
//    /**
//     * 在抛出异常时，spring mvc会将mapping注解配置的produce属性丢弃。所以增加该方法，将方法指定的produce写回
//     *
//     * @param request
//     * @param handlerMethod
//     */
//    private void addMethodProduces(WebRequest request, HandlerMethod handlerMethod) {
//        String[] produces = null;
//        // 当前仅支持Get和post两种请求
//        GetMapping getMapping = handlerMethod.getMethodAnnotation(GetMapping.class);
//        if (null != getMapping) {
//            produces = getMapping.produces();
//        } else {
//            PostMapping postMapping = handlerMethod.getMethodAnnotation(PostMapping.class);
//            if (null != postMapping) {
//                produces = postMapping.produces();
//            }
//        }
//        if (null != produces) {
//            Set<MediaType> mediaTypes = new HashSet<>(produces.length);
//            for (String produce : produces) {
//                mediaTypes.add(MediaType.parseMediaType(produce));
//            }
//            // 设置到request的属性中，在spring mvc获取convertor时，会根据该值获取
//            request.setAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes, WebRequest.SCOPE_REQUEST);
//        }
//    }
//
//    @Override
//    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
//                                                             HttpStatus status, WebRequest request) {
//        if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
//            request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
//            LOGGER.error("", ex);
//        }
//        Response errorBody = new Response();
//        errorBody.setStatus(Response.Status.FAILED);
//        errorBody.setErrorCode("SYS." + String.valueOf(status.value()));
//        errorBody.setErrorMessage(status.getReasonPhrase());
//        errorBody.setExtMessage(ex.getMessage());
//
//        return new ResponseEntity<>(errorBody, headers, HttpStatus.OK);
//    }
//
//    @Override
//    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
//        List<String> details = new ArrayList<>();
//        for (ObjectError error : ex.getBindingResult().getAllErrors()) {
//            details.add(error.getDefaultMessage());
//        }
//        Response errorBody = new Response();
//
//        String errMessage = "input parameters invalid:" + details.stream().collect(Collectors.joining(","));
//        errorBody.setStatus(Response.Status.FAILED);
//        errorBody.setErrorCode("SYS." + String.valueOf(status.value()));
//        errorBody.setErrorMessage(status.getReasonPhrase());
//        errorBody.setExtMessage(errMessage);
//
//        logger.error(errMessage);
//
//        return new ResponseEntity(errorBody, HttpStatus.OK);
//    }
//}
